package com.hunttown.mes.manage.service;

import com.hunttown.mes.common.cache.Cache;
import com.hunttown.mes.common.keys.KeyConstants;
import com.hunttown.mes.common.utils.FormatUtils;
import com.hunttown.mes.common.utils.StringUtils;
import com.hunttown.mes.rpc.api.AnalysisManageRightMenuRpcService;
import com.hunttown.mes.rpc.domain.query.AnalysisManageRightRoleMenuRelDTOQuery;
import com.hunttown.mes.rpc.domain.AnalysisManageRightMenuDTO;
import com.hunttown.mes.rpc.domain.query.AnalysisManageRightMenuDTOQuery;
import com.hunttown.common.domain.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * created by hunttown on 2018-10-26 15:04:54
 */
@Service
public class AnalysisManageRightMenuManageService {

    private final static Logger logger = LoggerFactory.getLogger(AnalysisManageRightMenuManageService.class);

    private final Cache jedisCache;
    private final AnalysisManageRightMenuRpcService rpcService;
    private final AnalysisManageRightRoleMenuRelManageService roleMenuRelService;

    @Autowired
    public AnalysisManageRightMenuManageService(Cache jedisCache, AnalysisManageRightMenuRpcService rpcService, AnalysisManageRightRoleMenuRelManageService roleMenuRelService) {
        this.jedisCache = jedisCache;
        this.rpcService = rpcService;
        this.roleMenuRelService = roleMenuRelService;
    }

    // 新增
    public AnalysisManageRightMenuDTO insert(AnalysisManageRightMenuDTO objDTO) {
        return rpcService.insert(objDTO);
    }

    // 通过ID修改
    public Boolean updateInfoById(AnalysisManageRightMenuDTO objDTO) {
        Boolean isNext = rpcService.updateInfoById(objDTO);
        if (isNext) {
            // 刷新缓存
            refreshCacheById(objDTO.getId());
        }
        return isNext;
    }

    // 通过Query修改
    public Boolean updateInfoByQuery(AnalysisManageRightMenuDTOQuery objDTOQuery) {
        Boolean isNext = rpcService.updateInfoByQuery(objDTOQuery);

        //单体刷新
        if (isNext && objDTOQuery.getW_id() != null) {
            refreshCacheById(objDTOQuery.getW_id());
        }
        return isNext;
    }

    // 通过ID删除
    public Boolean delete(Integer id) {
        Boolean isNext = rpcService.deleteById(id);
        if (isNext) {
            // 刷新缓存
            refreshCacheById(id);
        }
        return isNext;
    }

    // 批量删除
    public Boolean deleteForBatch(String clearIds) {

        //处理 “,5,6,7,” 为List
        List<Integer> idList = FormatUtils.commaToList_Integer(clearIds);

        if (idList.size() == 0) {
            return false;
        }

        AnalysisManageRightMenuDTOQuery query = new AnalysisManageRightMenuDTOQuery();
        query.setDeleteFlag(1);
        query.setIds(idList);

        return rpcService.updateInfoByQuery(query);
    }

    // 通过ID获取
    public AnalysisManageRightMenuDTO getById(Integer id) {
        if (id <= 0) {
            return null;
        }
        return rpcService.selectById(id);
    }

    // 通过Query获取
    public AnalysisManageRightMenuDTO getByQuery(AnalysisManageRightMenuDTOQuery objDTOQuery) {
        return rpcService.selectObjByQuery(objDTOQuery);
    }

    // 获取分页列表
    public Page<AnalysisManageRightMenuDTO> getForPage(AnalysisManageRightMenuDTOQuery objDTOQuery) {
        return rpcService.getListForPage(objDTOQuery);
    }

    // 改变某条记录的使用状态
    public Boolean changeState(Integer id, Integer state) {
        AnalysisManageRightMenuDTO obj = new AnalysisManageRightMenuDTO();
        obj.setStopFlag(state);
        obj.setId(id);
        return updateInfoById(obj);
    }

    /**
     * 构建左侧分类树 A2-1
     *
     * @param menuType 0基础菜单，1checkbox菜单
     * @param roleId   角色ID
     * @return
     */
    public List<String> createCateTree(Integer menuType, Integer roleId) {
        AnalysisManageRightMenuDTOQuery menuDTOQuery = new AnalysisManageRightMenuDTOQuery();
        menuDTOQuery.setPageSize(10000);
        menuDTOQuery.setOrderBy("order by sort asc, id asc");
        List<AnalysisManageRightMenuDTO> list = rpcService.getListForPage(menuDTOQuery).getItems();

        List<Integer> roleList = new ArrayList<>();
        if (menuType == 1 && roleId > 0) {
            AnalysisManageRightRoleMenuRelDTOQuery query = new AnalysisManageRightRoleMenuRelDTOQuery();
            query.setPageSize(10000);
            query.setRoleId(roleId);

            roleMenuRelService.getForPage(query).getItems().forEach(s -> roleList.add(s.getMenuId()));
        }

        return getList(list, 0, roleList, menuType, 0);
    }

    /**
     * 递归 A2-2
     *
     * @param mainList 所有菜单
     * @param parentId 父ID，为了选择它的子集
     * @param roleList 已选中的菜单
     * @param menuType 0基础菜单，1checkbox菜单
     * @param deep     菜单深度
     * @return
     */
    private List<String> getList(List<AnalysisManageRightMenuDTO> mainList, Integer parentId, List<Integer> roleList, Integer menuType, Integer deep) {

        List<String> result = new ArrayList<>();

        if (mainList == null || mainList.size() == 0) {
            return result;
        }

        deep += 1;

        List<AnalysisManageRightMenuDTO> filterList = mainList.stream().filter(s -> s.getParentId().equals(parentId)).collect(Collectors.toList());

        if (filterList.size() == 0) {
            return result;
        }

        // 是否菜单标识
        String menuSign = "";
        // 启用停用标识
        String stopFlag = "";
        // 菜单选中标识
        String chkSign = "";
        // 菜单展开标识
        String openSign = "";

        result.add("<ul>");
        for (AnalysisManageRightMenuDTO item : filterList) {
            if (item.getPathType().equals(0)) {
                menuSign = "（N）";
            } else {
                menuSign = "";
            }

            if (item.getStopFlag().equals(1)) {
                stopFlag = "（停用）";
            } else {
                stopFlag = "";
            }

            if (menuType == 1) {
                if (roleList != null && roleList.size() > 0) {
                    if (roleList.contains(item.getId())) {
                        chkSign = ", \"selected\":true";
                    } else {
                        chkSign = "";
                    }
                }
            }

            if (deep > 5) {
                openSign = "\"opened\":false ";
            } else {
                openSign = "\"opened\":true ";
            }

            result.add("<li data-jstree='{" + openSign + chkSign + "}' menuId='" + item.getId() + "'><a href='javascript:void(0);' onclick='manageMenuEditUrl(" + item.getId() + ", " + item.getParentId() + ")'>" + item.getMenuName() + stopFlag + menuSign + "</a>");

            //递归
            List<String> list = getList(mainList, item.getId(), roleList, menuType, deep);
            for (String child : list) {
                result.add(child);
            }

            result.add("</li>");
        }
        result.add("</ul>");

        return result;
    }

    //根据cateId获取对象
    public AnalysisManageRightMenuDTO getByCateId(Integer cateId) {
        if (cateId <= 0) {
            return null;
        }

        return rpcService.selectById(cateId);
    }

    //通过递归方法获取上级信息 B2-1
    //适合数据较少、不太复杂的场景，因为时间复杂度较大。
    public String getParentInfo(Integer cateId) {
        if (cateId <= 0) {
            return null;
        }

        AnalysisManageRightMenuDTOQuery unionManageRightMenuDTOQuery = new AnalysisManageRightMenuDTOQuery();
        unionManageRightMenuDTOQuery.setPageSize(10000);
        List<AnalysisManageRightMenuDTO> list = rpcService.getListForPage(unionManageRightMenuDTOQuery).getItems();

        String result = getParentInfoRecursion(list, cateId);
        return result;
    }

    //B2-2
    private String getParentInfoRecursion(List<AnalysisManageRightMenuDTO> mainList, Integer cateId) {
        String result = null;

        if (mainList == null || mainList.size() == 0) {
            return result;
        }

        List<AnalysisManageRightMenuDTO> filterList = mainList.stream().filter(s -> s.getId().equals(cateId)).collect(Collectors.toList());

        if (filterList == null || filterList.size() == 0) {
            return result;
        }

        for (AnalysisManageRightMenuDTO item : filterList) {
            if (result == null) {
                result = item.getMenuName();
            } else {
                result = String.format("%s > %s", item.getMenuName(), result);
            }

            if (item.getParentId() > 0) {
                String str = getParentInfoRecursion(mainList, item.getParentId());
                result = String.format("%s > %s", str, result);
            }
        }

        return result;
    }

    //获取列表，下拉菜单使用 C2-1
    public List<String> getListForDropdown(Integer selectId) {
        AnalysisManageRightMenuDTOQuery unionManageRightMenuDTOQuery = new AnalysisManageRightMenuDTOQuery();
        unionManageRightMenuDTOQuery.setPageSize(10000);
        List<AnalysisManageRightMenuDTO> list = rpcService.getListForPage(unionManageRightMenuDTOQuery).getItems();

        return getListForDropdownRecursion(list, 0, "|", selectId);
    }

    //C2-2
    private List<String> getListForDropdownRecursion(List<AnalysisManageRightMenuDTO> mainList, Integer parentId, String markSign, Integer selectId) {
        List<String> result = new ArrayList<>();

        if (mainList == null || mainList.size() == 0) {
            return result;
        }

        List<AnalysisManageRightMenuDTO> filterList = mainList.stream().filter(s -> s.getParentId().equals(parentId)).collect(Collectors.toList());

        if (filterList == null || filterList.size() == 0) {
            return result;
        }

        if (parentId > 0) {
            markSign += "----";
        }

        String selectStr = "";
        String stopFlag = "";

        for (AnalysisManageRightMenuDTO item : filterList) {
            if (Objects.equals(item.getId(), selectId)) {
                selectStr = "selected=\"selected\"";
            } else {
                selectStr = "";
            }

            if (item.getStopFlag().equals(1)) {
                stopFlag = "（停用）";
            } else {
                stopFlag = "";
            }

            if (parentId == 0) {
                result.add("<option value=\"" + item.getId() + "\" style=\"font-weight:bold;\" " + selectStr + ">" + item.getMenuName() + stopFlag + "</option>");
            } else {
                result.add("<option value=\"" + item.getId() + "\" " + selectStr + ">" + markSign + " " + item.getMenuName() + stopFlag + "</option>");
            }

            //递归
            List<String> list = getListForDropdownRecursion(mainList, item.getId(), markSign, selectId);
            for (String child : list) {
                result.add(child);
            }
        }

        return result;
    }

    //递归获取分类和它的子分类 D2-1
    public List<Integer> getCateIdList(Integer cateId) {
        AnalysisManageRightMenuDTOQuery unionManageRightMenuDTOQuery = new AnalysisManageRightMenuDTOQuery();
        unionManageRightMenuDTOQuery.setPageSize(10000);
        List<AnalysisManageRightMenuDTO> list = rpcService.getListForPage(unionManageRightMenuDTOQuery).getItems();

        return getCateIdListRecursion(list, cateId);
    }

    //D2-2
    private List<Integer> getCateIdListRecursion(List<AnalysisManageRightMenuDTO> mainList, Integer cateId) {
        List<Integer> result = new ArrayList<>();
        if (!result.contains(cateId)) {
            result.add(cateId);
        }

        List<AnalysisManageRightMenuDTO> filterList = mainList.stream().filter(s -> s.getParentId().equals(cateId)).collect(Collectors.toList());
        for (AnalysisManageRightMenuDTO item : filterList) {
            List<Integer> list = getCateIdListRecursion(mainList, item.getId());
            for (Integer child : list) {
                if (!result.contains(child)) {
                    result.add(child);
                }
            }
        }

        return result;
    }

    //循环获取产品分类名称，这里不使用递归，在性能上不如几次有限的循环 E1-1
    public String getProCateNameAll(List<AnalysisManageRightMenuDTO> proCateList, Integer proCateId) {
        String pro_cate_name = "";
        AnalysisManageRightMenuDTO pro_cate_obj = null;

        for (int i = 0; i < 10; i++) {
            for (AnalysisManageRightMenuDTO pro_cate_item : proCateList) {
                if (pro_cate_item.getId().equals(proCateId)) {
                    pro_cate_obj = pro_cate_item;
                    break;
                }
            }

            //设置最大循环次数为10，如果取不到数据则停止循环
            if (pro_cate_obj == null) {
                break;
            }

            //拼接name
            if (Objects.equals(pro_cate_name, "")) {
                pro_cate_name = pro_cate_obj.getMenuName();
            } else {
                pro_cate_name = String.format("%s>%s", pro_cate_obj.getMenuName(), pro_cate_name);
            }

            //准备下一次循环的cate_id
            proCateId = pro_cate_obj.getParentId();
            pro_cate_obj = null;

            if (proCateId == 0) {
                break;  //如果当前记录的父id为0，则说明已经是顶级了
            }
        }

        return pro_cate_name;
    }

    //通过唯一代码获取记录
    public AnalysisManageRightMenuDTO getByMenuCode(String menuCode) {
        AnalysisManageRightMenuDTOQuery unionManageRightMenuDTOQuery = new AnalysisManageRightMenuDTOQuery();
        unionManageRightMenuDTOQuery.setMenuNameEn(menuCode);
        List<AnalysisManageRightMenuDTO> list = rpcService.getListForPage(unionManageRightMenuDTOQuery).getItems();

        if (list == null || list.size() == 0) {
            return null;
        }
        return list.get(0);
    }

    //获取菜单ID，先从缓存中获取
    public Integer getMenuIdFromCacheCode(String code) {
        if (StringUtils.isBlank(code)) {
            return 0;
        }

        AnalysisManageRightMenuDTO obj = jedisCache.oget(KeyConstants.MENU_INFO_CACHE_KEY_CODE + code, AnalysisManageRightMenuDTO.class);
        if (obj == null) {
            obj = getByMenuCode(code);
            if (obj != null) {
                jedisCache.oset(KeyConstants.MENU_INFO_CACHE_KEY_CODE + code, obj);
            }
        }

        return obj == null ? 0 : obj.getId();
    }

    //region 刷新缓存

    /**
     * 刷新菜单缓存
     *
     * @param id 菜单id
     */
    public void refreshCacheById(Integer id) {
        if (id == null || id <= 0) {
            return;
        }

        AnalysisManageRightMenuDTO obj = getById(id);
        if (obj != null) {
            jedisCache.delete(KeyConstants.MENU_INFO_CACHE_KEY_CODE + obj.getMenuNameEn());
        }
    }

    /**
     * 刷菜单缓存(批量)
     *
     * @param idList
     */
    public void refreshCacheByIdList(List<Integer> idList) {
        if (idList == null || idList.size() == 0) {
            return;
        }

        for (Integer id : idList) {
            refreshCacheById(Integer.valueOf(id.toString()));
        }
    }
    //endregion
}